home *** CD-ROM | disk | FTP | other *** search
- /* $Revision Header *** Header built automatically - do not edit! ***********
- *
- * (C) Copyright 1992 by Amit Fridman
- *
- * Name .....: Virtual.c
- * Created ..: Friday 13-Nov-92 15:21:53
- * Revision .: 1
- *
- * Date Author Comment
- * ========= ==================== ====================
- * 14-Nov-92 Amit Fridman Version 1.0 finished
- * 13-Nov-92 Amit Fridman Created this file!
- *
- * $Revision Header ********************************************************/
- #define REVISION 1
-
- #include <exec/memory.h>
- #include <libraries/dos.h>
- #include <string.h>
- #include "Virtual.h"
-
- static char *VMFindBase(struct VirtMem *vm,struct SegEntry *seg,ULONG size,struct SegEntry **postseg,struct SegEntry **preseg);
-
-
- BOOL InitVirtualMem(struct VirtMem *vm,const char *FName,
- ULONG VirtSize,ULONG PhysSize,USHORT SegNum)
- {
- vm->File=Open(FName,MODE_NEWFILE);
- if (vm->File) {
- vm->PhysMem=AllocMem(PhysSize,0);
- if (vm->PhysMem) {
- vm->Segments=AllocMem(SegNum*sizeof(struct SegEntry),MEMF_CLEAR);
- if (vm->Segments) {
- vm->PSegments=NULL;
- vm->VirtSize=VirtSize;
- vm->PhysSize=PhysSize;
- vm->SegNum=SegNum;
- strcpy(vm->FName,FName);
- vm->AccOffset=0;
- vm->Count=0;
- return(TRUE);
- }
- }
- FreeMem(vm->PhysMem,PhysSize);
- }
- Close(vm->File);
- return(FALSE);
- }
-
- void FreeVirtMem(struct VirtMem *vm)
- {
- FreeMem(vm->Segments,vm->SegNum*sizeof(struct SegEntry));
- FreeMem(vm->PhysMem,vm->PhysSize);
- Close(vm->File);
- DeleteFile(vm->FName);
- }
-
- struct SegEntry *CreateSegment(struct VirtMem *vm,ULONG size,SHORT pri)
- {
- register int i;
- struct SegEntry *seg;
-
- if (size>vm->PhysSize) return(NULL);
- for (i=0; i<vm->SegNum; i++)
- if (!(vm->Segments[i].Flags & SF_USED)) break;
- if (i==vm->SegNum) return(NULL);
- seg=&vm->Segments[i];
- seg->NextP=NULL;
- seg->Base=NULL;
- seg->Size=size;
- seg->FOffset=vm->AccOffset;
- seg->Access=0;
- seg->Pri=pri;
- seg->Flags=SF_USED;
- vm->AccOffset+=size;
- Seek(vm->File,seg->FOffset,OFFSET_BEGINNING);
- Write(vm->File,vm->PhysMem,size);
- return(seg);
- }
-
- BOOL Access(struct VirtMem *vm,struct SegEntry *seg)
- {
- char *Base;
- struct SegEntry *seg1,*seg2;
- ULONG len;
-
- seg->Access=vm->Count;
- vm->Count++;
- if (seg->Flags & SF_PRESENT) return(TRUE);
- Base=VMFindBase(vm,seg,seg->Size,&seg1,&seg2);
- seg->Base=Base;
- seg->Flags|=SF_PRESENT;
- seg->NextP=seg1;
- if (seg2)
- seg2->NextP=seg;
- else
- vm->PSegments=seg;
- if (!(seg->Flags & SF_INFILE)) return(TRUE);
- Seek(vm->File,seg->FOffset,OFFSET_BEGINNING);
- len=Read(vm->File,seg->Base,seg->Size);
- return(len==seg->Size);
- }
-
- static char *VMFindBase(struct VirtMem *vm,struct SegEntry *seg,ULONG size,
- struct SegEntry **postseg,struct SegEntry **preseg)
- {
- struct SegEntry *seg1,*seg2;
- char *Base;
- SHORT lowPri;
- ULONG access;
- struct SegEntry *ss1,*ss2;
-
- while (1) {
- Base=vm->PhysMem;
- seg1=vm->PSegments;
- if (!seg1) {
- *postseg=NULL;
- *preseg=NULL;
- return(Base);
- }
- seg2=NULL;
- while (seg1) {
- if (Base+size<=seg1->Base) {
- *postseg=seg1;
- *preseg=seg2;
- return(Base);
- }
- Base=seg1->Base+seg1->Size;
- seg2=seg1;
- seg1=seg1->NextP;
- }
- if (Base+size<=vm->PhysMem+vm->PhysSize) {
- *postseg=seg1;
- *preseg=seg2;
- return(Base);
- }
- lowPri=32767;
- access=1<<31;
- for (seg1=vm->PSegments,seg2=NULL; seg1; seg2=seg1,seg1=seg1->NextP)
- if (seg1->Pri<lowPri) {
- lowPri=seg1->Pri;
- access=seg1->Access;
- ss1=seg1;
- ss2=seg2;
- } else
- if ((seg1->Pri==lowPri) && (seg1->Access<access)) {
- access=seg1->Access;
- ss1=seg1;
- ss2=seg2;
- }
- if (ss2)
- ss2->NextP=ss1->NextP;
- else
- vm->PSegments=ss1->NextP;
- if (ss1->Flags & SF_DIRTY) {
- Seek(vm->File,ss1->FOffset,OFFSET_BEGINNING);
- Write(vm->File,ss1->Base,ss1->Size);
- ss1->Flags^=SF_DIRTY;
- }
- ss1->Flags^=SF_PRESENT;
- ss1->Flags|=SF_INFILE;
- }
- return(NULL);
- }
-